const app = getApp()

function inArray(arr, key, val) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i;
    }
  }
  return -1;
}
// 16进制转字符串
function hex2str(hex) {
  　　var trimedStr = hex.trim();
  　　var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
  　　var len = rawStr.length;
  　　if (len % 2 !== 0) {
    　　　　alert("Illegal Format ASCII Code!");
    　　　　return "";
  　　}
  　　var curCharCode;
  　　var resultStr = [];
  　　for (var i = 0; i < len; i = i + 2) {
    　　　　curCharCode = parseInt(rawStr.substr(i, 2), 16);
    　　　　resultStr.push(String.fromCharCode(curCharCode));
  　　}
  　　return resultStr.join("");
}
function stringToHex(str) {
  var val = "";
  for (var i = 0; i < str.length; i++) {
    val += str.charCodeAt(i).toString(16);
  }
  return val;
}

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  var hexArr = Array.prototype.map.call(    
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}

Page({
  data: {
    devices: [],
    connected: false,
    chs: [],
  },
  openBluetoothAdapter() {
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('openBluetoothAdapter success', res)
        this.startBluetoothDevicesDiscovery()
      },
      fail: (res) => {
        if (res.errCode === 10001) {
          wx.onBluetoothAdapterStateChange(function (res) {
            console.log('onBluetoothAdapterStateChange', res)
            if (res.available) {
              this.startBluetoothDevicesDiscovery()
            }
          })
        }
      }
    })
  },
  getBluetoothAdapterState() {
    wx.getBluetoothAdapterState({
      success: (res) => {
        console.log('getBluetoothAdapterState', res)
        if (res.discovering) {
          this.onBluetoothDeviceFound()
        } else if (res.available) {
          this.startBluetoothDevicesDiscovery()
        }
      }
    })
  },
  startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return
    }
    this._discoveryStarted = true
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success: (res) => {
        console.log('startBluetoothDevicesDiscovery success', res)
        this.onBluetoothDeviceFound()
      },
    })
  },
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery()
  },
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (!device.name && !device.localName) {
          return
        }
        const foundDevices = this.data.devices
        const idx = inArray(foundDevices, 'deviceId', device.deviceId)
        const data = {}
        if (idx === -1) {
          data[`devices[${foundDevices.length}]`] = device
        } else {
          data[`devices[${idx}]`] = device
        }
        this.setData(data)
      })
    })
  },
  createBLEConnection(e) {
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        this.setData({
          connected: true,
          name,
          deviceId,
        })
        this.getBLEDeviceServices(deviceId)
      }
    })
    this.stopBluetoothDevicesDiscovery()
  },
  closeBLEConnection() {
    wx.closeBLEConnection({
      deviceId: this.data.deviceId
    })
    this.setData({
      connected: false,
      chs: [],
      canWrite: false,
    })
  },
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        for (let i = 0; i < res.services.length; i++) {
          if (res.services[i].isPrimary) {
            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            return
          }
        }
      }
    })
  },
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        console.log('getBLEDeviceCharacteristics success', res.characteristics)
        for (let i = 0; i < res.characteristics.length; i++) {
          let item = res.characteristics[i]
          if (item.properties.read) {
            wx.readBLECharacteristicValue({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            })
          }
          if (item.properties.write) {
            this.setData({
              canWrite: true
            })
            this._deviceId = deviceId
            this._serviceId = serviceId
            this._characteristicId = item.uuid
            this.cmdInit()
          }
          if (item.properties.notify || item.properties.indicate) {
            wx.notifyBLECharacteristicValueChange({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true,
            })
          }
        }
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics', res)
      }
    })
    // 操作之前先监听，保证第一时间获取数据
    wx.onBLECharacteristicValueChange((characteristic) => {
      const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
      const data = {}
      if (idx === -1) {
        data[`chs[${this.data.chs.length}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      } else {
        data[`chs[${idx}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      }
      // data[`chs[${this.data.chs.length}]`] = {
      //   uuid: characteristic.characteristicId,
      //   value: ab2hex(characteristic.value)
      // }
      this.setData(data)
    })
  },
  cmdInit() {
    // 向蓝牙设备发送一个0x00的16进制数据
    let buffer = new ArrayBuffer(3)
    let dataView = new DataView(buffer)
    // get global info 
    dataView.setUint8(0, 0xA0)
    dataView.setUint8(1, 0x01)
    dataView.setUint8(2, 0x00)
    let _this = this
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: buffer,
      success(res) {
        console.log('写入数据成功', res.errMsg)
        console.log('res', res)
        _this.readDevice(_this._deviceId, _this._serviceId, _this._characteristicId)
      },
      fail(err) {
        console.log('err', err)
      }
    })

  },
  sale() {
    let _this = this
    // 向蓝牙设备发送一个0x00的16进制数据
    // var resultStr = [];
    // resultStr.push(hex2str('0xA1'))
    // resultStr.push(hex2str('0x0D'))
    // resultStr.push('1234561234561')
    var data = '1234561234561'
    // var data = resultStr.join("");
    let buffer = new ArrayBuffer(data.length*2);
     buffer = 'A10D'+stringToHex(data)
    var typedArray = new Uint8Array(buffer.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    var bufferdata = typedArray.buffer
    // dataView.setUint8(0, 0xA1)
    // dataView.setUint8(1, 0x0D)
    // dataView.setUint8(2, '1')
    // dataView.setUint8(3, '2')
    // dataView.setUint8(4, '3')
    // dataView.setUint8(5, '4')
    // dataView.setUint8(6, '5')
    // dataView.setUint8(7, '6')
    // dataView.setUint8(8, '1')
    // dataView.setUint8(9, '2')
    // dataView.setUint8(10, '3')
    // dataView.setUint8(11, '4')
    // dataView.setUint8(12, '5')
    // dataView.setUint8(13, '6')
    // dataView.setUint8(14, '1')

    // const hex = _this.buf2hex(bufferdata);
    // console.log("请求数据" , bufferdata); 
    // console.log("请求数据Hex " + hex);
    // console.log("请求字符串：" + hex2str(hex));
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: bufferdata, 
      success(res) {
        console.log('写入数据成功', res.errMsg)
        console.log('res', res)
        _this.readDevice(_this._deviceId, _this._serviceId, _this._characteristicId)
      },
      fail(err) {
        console.log('err', err)
      }
    })
  },
  replenishment() {
    let _this = this
    // 向蓝牙设备发送一个0x00的16进制数据
    // var resultStr = [];
    // resultStr.push(hex2str('0xA1'))
    // resultStr.push(hex2str('0x0D'))
    // resultStr.push('1234561234561')
    var data = '1234561'
    // var data = resultStr.join("");
    let buffer = new ArrayBuffer(data.length * 2);
    buffer = '0xA207'+stringToHex(data)
    var typedArray = new Uint8Array(buffer.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    var bufferdata = typedArray.buffer
    const hex = _this.buf2hex(bufferdata);
    // console.log("请求数据", bufferdata);
    // console.log("请求数据Hex " + hex);
    // console.log("请求字符串：" + hex2str(hex));
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: bufferdata,
      success(res) {
        console.log('写入数据成功', res.errMsg)
        console.log('res', res)
        _this.readDevice(_this._deviceId, _this._serviceId, _this._characteristicId)
      },
      fail(err) {
        console.log('err', err)
      }
    })
  },
  recharge() {
    let _this = this
    // 向蓝牙设备发送一个0x00的16进制数据
    // var resultStr = [];
    // resultStr.push(hex2str('0xA1'))
    // resultStr.push(hex2str('0x0D'))
    // resultStr.push('1234561234561')
    var data = '1234561234561'
    // var data = resultStr.join("");
    let buffer = new ArrayBuffer(data.length * 2);
    buffer = '0xA30D'+stringToHex(data)
    var typedArray = new Uint8Array(buffer.match(/[\da-f]{2}/gi).map(function (h) {
      return parseInt(h, 16)
    }))
    var bufferdata = typedArray.buffer
    const hex = _this.buf2hex(bufferdata);
    console.log("请求数据", bufferdata);
    console.log("请求数据Hex " + hex);
    console.log("请求字符串：" + hex2str(hex));
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: bufferdata,
      success(res) {
        console.log('写入数据成功', res.errMsg)
        console.log('res', res)
        _this.readDevice(_this._deviceId, _this._serviceId, _this._characteristicId)
      },
      fail(err) {
        console.log('err', err)
      }
    })
  },
  readSale(deviceId, serviceId, characteristicId) {
    let _this = this
    // 必须在这里的回调才能获取 
    wx.onBLECharacteristicValueChange(function (characteristic) {
      console.log('characteristic value comed:', characteristic)
      const hex = _this.buf2hex(characteristic.value);
      console.log("run-shoes返回的数据：" + hex);
      console.log("run-shoes：" + hex2str(hex));
      // var responsebuffer = characteristic.value
      // var cmd = responsebuffer.getUint8(0);
      // var length = responsebuffer.getUint8(1);
      // var data = responsebuffer.getUint8(2);
      var databuffer = characteristic.value

      var cmd = new DataView(databuffer, 0, 1);
      var length = new DataView(databuffer, 1, 1);
      var mac = new DataView(databuffer, 2, 6);
      var password = new DataView(databuffer, 8, 6);
      // var workstatus = new DataView(databuffer, 14, 1)

      console.log('cmd:', parseInt(cmd, 2).toString(16))
      console.log('length:', parseInt(length, 2).toString(16))
      console.log('mac:', mac.getUint8())
      console.log('password:', hex2str(_this.buf2hex(password.buffer)))
      // console.log('workstatus:', workstatus.getUint8())
    })

    wx.readBLECharacteristicValue({
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
      deviceId,
      // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
      serviceId,
      // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
      characteristicId,
      success(res) {
        console.log('readBLECharacteristicValue:', res)
      }
    })
  },
  readDevice(deviceId, serviceId, characteristicId) {
    let _this = this
    // 必须在这里的回调才能获取 
    wx.onBLECharacteristicValueChange(function (characteristic) {
      console.log('characteristic value comed:', characteristic)
      // console.log('ab2ascii:', ab2Ascii(characteristic.value))
      const hex = _this.buf2hex(characteristic.value);
      console.log("run-shoes返回的数据：" + hex);
      console.log("run-shoes：" + hex2str(hex));
      // var responsebuffer = characteristic.value
      // var cmd = responsebuffer.getUint8(0);
      // var length = responsebuffer.getUint8(1);
      // var data = responsebuffer.getUint8(2);

      var databuffer = characteristic.value

      var cmd = new DataView(databuffer, 0, 1);
      var length = new DataView(databuffer, 1, 1);
      var mac = new DataView(databuffer, 2, 6);
      var password = new DataView(databuffer, 8, 6);
      // var workstatus = new DataView(databuffer, 14, 1)

      console.log('cmd:', parseInt(cmd, 2).toString(16))
      console.log('length:', parseInt(length, 2).toString(16))
      console.log('mac:', mac.getUint8())
      console.log('password:', hex2str(_this.buf2hex(password.buffer)))
      // console.log('workstatus:', workstatus.getUint8())
    })

    wx.readBLECharacteristicValue({
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
      deviceId,
      // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
      serviceId,
      // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
      characteristicId,
      success(res) {
        console.log('readBLECharacteristicValue:', res)
      }
    })
  },
  closeBluetoothAdapter() {
    wx.closeBluetoothAdapter()
    this._discoveryStarted = false
    this.setData({
      devices: []
    })
  },
  // 控制台无法打印ArrayBuffer数据，解码ArrayBuffer,
  buf2hex: function (buffer) {
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  },
})
